/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* $Id: ColumnSetup.java,v 1.1 2007/04/12 06:41:19 cvsuser Exp $ */

package com.wisii.wisedoc.layoutmanager.table;

import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import com.wisii.wisedoc.document.Table;
import com.wisii.wisedoc.document.TableColumn;
import com.wisii.wisedoc.document.datatype.PercentBaseContext;
import com.wisii.wisedoc.log.LogUtil;

/**
 * Class holding a number of columns making up the column setup of a row.
 */
public class ColumnSetup {

	private Table table;
	private List columns = new java.util.ArrayList();
	private int maxColIndexReferenced = 0;

	/**
	 * Main Constructor.
	 * 
	 * @param table
	 *            the table to construct this column setup for
	 */
	public ColumnSetup(Table table) {
		this.table = table;
		prepareExplicitColumns();
		if (getColumnCount() == 0) {
			createColumnsFromFirstRow();
		}
	}

	private void prepareExplicitColumns() {
		List rawCols = table.getColumns();
		if (rawCols != null) {
			int colnum = 1;
			ListIterator iter = rawCols.listIterator();
			while (iter.hasNext()) {
				TableColumn col = (TableColumn) iter.next();
				if (col == null) {
					continue;
				}
				colnum = col.getColumnNumber();
				for (int i = 0; i < col.getNumberColumnsRepeated(); i++) {
					while (colnum > columns.size()) {
						columns.add(null);
					}
					columns.set(colnum - 1, col);
					colnum++;
				}
			}
			// Post-processing the list (looking for gaps)
			int pos = 1;
			ListIterator ppIter = columns.listIterator();
			while (ppIter.hasNext()) {
				TableColumn col = (TableColumn) ppIter.next();
				if (col == null) {
					LogUtil.error("Found a gap in the table-columns at position "
							+ pos);
				}
				pos++;
			}
		}
	}

	/**
	 * Returns a column. If the index of the column is bigger than the number of
	 * explicitly defined columns the last column is returned.
	 * 
	 * @param index
	 *            index of the column (1 is the first column)
	 * @return the requested column
	 */
	public TableColumn getColumn(int index) {
		int size = columns.size();
		if (index > size) {
			if (index > maxColIndexReferenced) {
				maxColIndexReferenced = index;
				if (!(size == 1 && getColumn(1).isDefaultColumn())) {
					//TODO LOG
					/*LogUtil
							.warn(FONode
									.decorateWithContextInfo(
											"There are fewer table-columns than are needed. Column "
													+ index
													+ " was accessed although only "
													+ size
													+ " columns have been defined. "
													+ "The last defined column will be reused.",
											table));*/
					if (!table.isAutoLayout()) {
						LogUtil
								.warn("Please note that according XSL-FO 1.0 (7.26.9) says that "
										+ "the 'column-width' property must be specified for every "
										+ "column, unless the automatic table layout is used.");
					}
				}
			}
			return (TableColumn) columns.get(size - 1);
		} else {
			return (TableColumn) columns.get(index - 1);
		}
	}

	/** @see java.lang.Object#toString() */
	public String toString() {
		return columns.toString();
	}

	/** @return the number of columns in the setup. */
	public int getColumnCount() {
		if (maxColIndexReferenced > columns.size()) {
			return maxColIndexReferenced;
		} else {
			return columns.size();
		}
	}

	/** @return an Iterator over all columns */
	public Iterator iterator() {
		return this.columns.iterator();
	}

	private void createColumnsFromFirstRow() {
		// TODO Create oldColumns from first row here
		// --> rule 2 in "fixed table layout", see CSS2, 17.5.2
		// Alternative: extend oldColumns on-the-fly, but in this case we need
		// the
		// new property evaluation context so proportional-column-width() works
		// correctly.
		if (columns.size() == 0) {
			this.columns.add(table.getDefaultColumn());
		}
	}

	/**
	 * @param col
	 *            column index (1 is first column)
	 * @param context
	 *            the context for percentage based calculations
	 * @return the X offset of the requested column
	 */
	public int getXOffset(int col, PercentBaseContext context) {
		int xoffset = 0;
		for (int i = 1; i < col; i++) {
			if (getColumn(i) != null) {
				xoffset += getColumn(i).getColumnWidth().getValue(context);
			}
		}
		return xoffset;
	}

}
